package com.cdtye.itps.cms.service.summary;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cdtye.common.mybatiscore.base.BaseService;
import com.cdtye.common.webcore.constants.WebConstants;
import com.cdtye.common.webcore.web.BizException;
import com.cdtye.itps.cms.dao.enums.CommonFileType;
import com.cdtye.itps.cms.dao.result.CellRangeAddressExcelVo;
import com.cdtye.itps.cms.dao.summary.entity.JcjcEvalauationSummary;
import com.cdtye.itps.cms.dao.summary.vo.JcjcEvalauationSummaryVo;
import com.cdtye.itps.cms.mapper.summary.JcjcEvalauationSummaryMapper;
import com.cdtye.itps.cms.util.Convert;
import com.cdtye.itps.cms.util.ExpCommonHelper;
import com.cdtye.itps.cms.util.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.util.*;

/**
 * 动态监测评价 服务类
 * @author wzw
 * @date 2022-01-10
 */

@Service
public class JcjcEvalauationSummaryService extends BaseService<JcjcEvalauationSummaryMapper, JcjcEvalauationSummary> {

    @Autowired
    private JcjcEvalauationSummaryMapper modelMapper;

    /**
     * 列表查询
     */
    public List<JcjcEvalauationSummary> list(JcjcEvalauationSummaryVo vo){
        LambdaQueryWrapper<JcjcEvalauationSummary> wrapper = new LambdaQueryWrapper<>();
        //添加查询条件

        //物理删除表,查询非删除状态包括null
        wrapper.and(i->i.eq(JcjcEvalauationSummary::getDelFlag, WebConstants.NO).or().isNull(JcjcEvalauationSummary::getDelFlag));
        return modelMapper.selectList(wrapper);
    }

    /**
     * 分页查询，自定义sql语句
     */
    public IPage<Map<String,Object>> listPage(JcjcEvalauationSummaryVo vo){
        return modelMapper.list(vo.page(), vo);
    }

    private List<String> buildListYearMonth2(List<String> list){
        List<String> result=new ArrayList<>();
        list.stream().forEach(a->{
            result.add(a.replace("_","-"));
        });

        return result;
    }
    private void buildListYearMonth(JcjcEvalauationSummaryVo vo) throws ParseException {
        if(StringUtils.isBlank(vo.getBeginMonth())){
            throw new BizException("开始月份不能为空");
        }
        if(StringUtils.isBlank(vo.getEndMonth())){
            throw new BizException("结束月份不能为空");
        }
        Date date = DateUtils.parse(vo.getBeginMonth(),"yyyy-MM");
        Date endDate = DateUtils.parse(vo.getEndMonth(),"yyyy-MM");
        if(date.compareTo(endDate)>0){
            throw new BizException("开始月份应该小于结束月份");
        }
        String beginMonth=vo.getBeginMonth();
        List<String> list=new ArrayList<>();
        list.add(beginMonth.replace("-","_"));
        if(vo.getBeginMonth().equals(vo.getEndMonth())){
            vo.setListYearMonth(list);
            return;
        }

        while(true){
            date= DateUtils.addMonths(date,1);
            String endMonth = DateUtils.DateToString(date,"yyyy-MM");
            list.add(endMonth.replace("-","_"));
            if(vo.getEndMonth().equals(endMonth)){
                vo.setListYearMonth(list);
                break;
            }
        }
    }
    private void buildlistAllParam(JcjcEvalauationSummaryVo vo){
        List<String> railtypes=new ArrayList<>();
        String flag="true";
        if(StringUtils.isNotBlank(vo.getGt()) && flag.equals(vo.getGt())){
            railtypes.add("GT");
        }
        if(StringUtils.isNotBlank(vo.getPt()) && flag.equals(vo.getPt())){
            railtypes.add("PT");
        }
        vo.setRailtypes(railtypes);
    }
    public Map<String,Object> listAll(JcjcEvalauationSummaryVo vo) throws ParseException {
        Map<String,Object> m=new HashMap<>();
        buildListYearMonth(vo);
        buildlistAllParam(vo);
        if(vo.getListYearMonth().size()>12){
            throw new BizException("请保持时间范围在一年以内");
        }
        List<Map<String,String>> headTitle=buildHeadTitle(vo.getListYearMonth());
        List<Map<String,Object>> dataList=modelMapper.listAll(vo);
        Map<String,Integer> deptMap=buildDeptNap(dataList);
        List<String> nameList=new ArrayList();
        List<Map<String,Object>> excellectRateList=new ArrayList();
        List<Map<String,Object>> cdiList=new ArrayList();
        List<Map<String,Object>> totalScoreList=new ArrayList();
        dataList.stream().forEach(a->{
            nameList.add(a.get("lineName").toString());
            excellectRateList.add(buildexcellectRateMap(headTitle,a,"excellectRate"));
            cdiList.add(buildexcellectRateMap(headTitle,a,"cdi"));
            totalScoreList.add(buildexcellectRateMap(headTitle,a,"totalScore"));
            String deptId=a.get("deptId").toString();
            if(deptMap.containsKey(deptId)){
                a.put("rowspan",deptMap.get(deptId));
                deptMap.remove(deptId);
            }
        });
        m.put("dataList",dataList);
        m.put("headTitle",headTitle);
        m.put("monthData",buildListYearMonth2(vo.getListYearMonth()));
        m.put("nameList",nameList);
        m.put("excellectRateList",excellectRateList);
        m.put("cdiList",cdiList);
        m.put("totalScoreList",totalScoreList);
        return m;
    }

    public Map<String,Object> indexCDIList(String yearOrMonth){
        Map<String,Object> m=new LinkedHashMap<>();
        if ("月份".equals(yearOrMonth)){
            m.put("一月","94");
            m.put("二月","93");
            m.put("三月","86");
            m.put("四月","76");
            m.put("五月","81");
            m.put("六月","0");
            m.put("七月","0");
            m.put("八月","0");
            m.put("九月","0");
            m.put("十月","0");
            m.put("十一月","0");
            m.put("十二月","0");
        }else {
            m.put("2021","91");
            m.put("2022","89");
            m.put("2023","95");
            m.put("2024","97");
            m.put("2025","93");
        }
        return m;
    }

    public Map<String,Object> indexLineExcellentRate(){
        Map<String,Object> m=new HashMap<>();
        m.put("优良里程","593");
        m.put("检测里程","598");
        m.put("优良率","99");
        return m;
    }

    public Map<String,Object> indexMonthCDI(){
        Map<String,Object> m=new LinkedHashMap<>();
        m.put("CDI本月得分","86");
        return m;
    }

    public Map<String,Object> indexDetectData(){
        Map<String,Object> m=new LinkedHashMap<>();
        m.put("检测监测数据","3080");
        return m;
    }

    private Map<String,Object> buildexcellectRateMap(List<Map<String,String>> headTitle,Map<String,Object> a,String name){
        Map<String,Object> excellectRateMap=new HashMap<>();
        excellectRateMap.put("name",a.get("lineName").toString());
        excellectRateMap.put("type","line");
        excellectRateMap.put("stack","Total");
        List data=new ArrayList();
        headTitle.stream().forEach(b->{
            Double val = Convert.toDouble(a.get(name+b.get("yearMonth")),0.0);
            data.add(String.format("%.2f", val));
        });
        excellectRateMap.put("data",data);
        return excellectRateMap;
    }

    private  List<Map<String,String>> buildHeadTitle(List<String> list){
        List<Map<String,String>> headTitle=new ArrayList<>();
        list.stream().forEach(a->{
            Map<String,String> h=new HashMap<>();
            h.put("title",a.replace("_","年")+"月");
            h.put("yearMonth",a.replace("_",""));
            headTitle.add(h);
        });
        return headTitle;
    }
    private Map<String,Integer> buildDeptNap(List<Map<String,Object>> dataList){
        Map<String,Integer> deptMap=new HashMap<>();
        int count=0;
        for(int i=0;i<dataList.size();i++){
            Map<String,Object> a=dataList.get(i);
            String key=a.get("deptId").toString();
            if(deptMap.containsKey(key)){
                count=deptMap.get(key);
            }else{
                count=0;
            }
            deptMap.put(key,count+1);
        }
        return deptMap;
    }

    public void exportList(JcjcEvalauationSummaryVo vo, HttpServletResponse response) throws Exception{
        buildListYearMonth(vo);
        buildlistAllParam(vo);
        if(vo.getListYearMonth().size()>12){
            throw new BizException("请保持时间范围在一年以内");
        }
        List<Map<String,Object>> dataList= modelMapper.listAll(vo);
        List<CellRangeAddressExcelVo> listCell = buildHeadCellList(vo.getListYearMonth());
        List<Map<String,String>> headTitle=buildHeadTitle(vo.getListYearMonth());
        Map<String,Integer> deptMap=buildDeptNap(dataList);
        int fistRow=3;

        for(int i=0;i<dataList.size();i++){
            Map<String,Object> a=dataList.get(i);
            String deptId=a.get("deptId").toString();
            if(deptMap.containsKey(deptId)){
                a.put("rowspan",deptMap.get(deptId));
                CellRangeAddressExcelVo cell3 = new CellRangeAddressExcelVo(fistRow, fistRow+deptMap.get(deptId), 0, 0);
                listCell.add(cell3);
                fistRow+=deptMap.get(deptId)+1;
                deptMap.remove(deptId);
            }
        }


        List<List<String>> list2 = buildHead(vo);
        dataList.stream().forEach(a->{
            List<String> objects = new ArrayList<>();
            objects.add(a.get("deptName").toString());
            objects.add(a.get("lineName").toString());
            headTitle.stream().forEach(b->{
                String yearMonth=b.get("yearMonth");
                objects.add(a.get("excellectRate"+yearMonth).toString());
                objects.add(a.get("cdi"+yearMonth).toString());
                objects.add(a.get("totalScore"+yearMonth).toString());
            });
            objects.add(a.get("excellectRate").toString());
            objects.add(a.get("cdi").toString());
            objects.add(a.get("totalScore").toString());
            list2.add(objects);

        });

        Workbook workbook = ExpCommonHelper.exportStaticsData(list2, new ArrayList<>(), CommonFileType.EVALAUATION_SUMMARY);
        Sheet sheet = workbook.getSheetAt(0);
        //合并单元格
        for (CellRangeAddressExcelVo model : listCell) {
            sheet.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(model.getFirstRow(), model.getLastRow(),
                    model.getFirstCol(), model.getLastCol()));
        }

        ExpCommonHelper.exportCommonMethod(workbook, response, "动态检测评价");
    }
    private List<CellRangeAddressExcelVo> buildHeadCellList(List<String> months){
        List<CellRangeAddressExcelVo> listCell = new LinkedList<>();
        int fistRow=0;
        int lastRow=1;
        CellRangeAddressExcelVo cell1 = new CellRangeAddressExcelVo(fistRow, lastRow, 0, 0);
        CellRangeAddressExcelVo cell2 = new CellRangeAddressExcelVo(fistRow, lastRow, 1, 1);
        int begin=2;
        listCell.add(cell1);
        listCell.add(cell2);
        for(int i=0;i<months.size()+1;i++){
            CellRangeAddressExcelVo cell3 = new CellRangeAddressExcelVo(fistRow, fistRow, begin, begin+2);
            listCell.add(cell3);
            begin=begin+3;
        }
        return listCell;
    }

    private List<List<String>> buildHead(JcjcEvalauationSummaryVo vo){
        List<String> months=vo.getListYearMonth();
        List<List<String>> list=new ArrayList<>();
        List<String> objects = new ArrayList<>();
        objects.add("单位");
        objects.add("线路");
        months.stream().forEach(a->{
            objects.add(a.replace("_","年")+"月");
            objects.add(a.replace("_","年")+"月");
            objects.add(a.replace("_","年")+"月");
        });
        objects.add("综合评分");
        objects.add("综合评分");
        objects.add("综合评分");
        List<String> objects2 = new ArrayList<>();
        objects2.add("单位");
        objects2.add("线路");
        for(int i=0;i<months.size();i++){
            objects2.add("优良率");
            objects2.add("CDI");
            objects2.add("总分");
        }
        objects2.add("优良率");
        objects2.add("CDI");
        objects2.add("线路得分");
        list.add(objects);
        list.add(objects2);
        return list;
    }



}
